package user

import (
	"errors"

	"gitcode.com/G-YT/baoyou/server/global"
	"gitcode.com/G-YT/baoyou/server/model/manager"
	"gitcode.com/G-YT/baoyou/server/model/user"
	userReq "gitcode.com/G-YT/baoyou/server/model/user/request"
	userRes "gitcode.com/G-YT/baoyou/server/model/user/response"
	"gorm.io/gorm"
)

type BindService struct {
}

// BindManager 创建用户绑定健管师记录
// Author [G-YT](https://gitcode.com/G-YT)
func (bindService *BindService) BindManager(Bind *user.BindRecord) (err error) {
	err = global.GVA_DB.Where("userID = ?", Bind.UserID).Order("created_at Desc").Limit(1).First(&Bind).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) && Bind.Status == 1 {
		return errors.New("请勿重复提交申请")
	} else {
		Bind = &user.BindRecord{
			ManagerID: Bind.ManagerID,
			Status:    1,
			UserID:    Bind.UserID,
		}
		err = global.GVA_DB.Create(Bind).Error
	}
	return err
}

// UnBindManager 解绑健管师（用户端）
// Author [G-YT](https://gitcode.com/G-YT)
func (bindService *BindService) UnBindManager(uid uint) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var u user.User
		if err = tx.Where("id = ?", uid).First(&u).Error; err != nil {
			return err
		}
		if u.HealthManagerID == 0 {
			return errors.New("您还没有健管师，请尽快绑定")
		}

		var hm manager.HealthManager
		if err := tx.Where("hm_id = ?", u.HealthManagerID).First(&hm).Error; err != nil {
			return err
		}
		// 处理指针与下限
		if hm.PromoteNum == nil {
			zero := 0
			hm.PromoteNum = &zero
		}
		if *hm.PromoteNum > 0 {
			*hm.PromoteNum = *hm.PromoteNum - 1
		}
		if UpdateErr := tx.Model(&manager.HealthManager{}).Where("hm_id = ?", u.HealthManagerID).Update("promote_num", *hm.PromoteNum).Error; UpdateErr != nil {
			return UpdateErr
		}
		// 清空用户的健管师与服务站
		if UpdatesErr := tx.Model(&user.User{}).Where("id = ?", uid).Updates(map[string]interface{}{
			"health_manager_id":  0,
			"service_station_id": 0,
		}).Error; UpdatesErr != nil {
			return UpdatesErr
		}
		return nil
	})
}

// GetBindInfoList 获取绑定用户列表
// Author [G-YT](https://gitcode.com/G-YT)
func (bindService *BindService) GetBindInfoList(info userReq.BindRecordSearch) (list []userRes.BindUserInfo, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&user.BindRecord{}).Where("managerID = ? AND status = ?", info.ManagerID, 1).Preload("User")
	var Binds []user.BindRecord
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Find(&Binds).Error
	for _, value := range Binds {
		list = append(list, userRes.BindUserInfo{
			ID:       value.ID,
			UserID:   value.User.ID,
			UserName: value.User.Name,
			Phone:    value.User.Phone,
			Sex:      value.User.Sex,
			Avatar:   value.User.Avatar,
			Types:    value.User.Types,
			Province: value.User.Province,
			City:     value.User.City,
			Area:     value.User.Area,
			Addr:     value.User.Addr,
		})
	}
	return list, total, err
}

// UpdateBindStatus 修改绑定状态
// Author [g-qs](https://gitee.com/g-qs)
func (bindService *BindService) UpdateBindStatus(id uint, status string) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var bindInfo user.BindRecord
		err = tx.Model(&bindInfo).Where("id = ?", id).Update("status", status).Error
		if status == "2" { // 通过审核
			var newHealthManager manager.HealthManager
			if bIErr := tx.Where("id = ?", id).First(&bindInfo).Error; bIErr != nil {
				return bIErr
			}
			// 获取新健管师信息
			if nHMErr := tx.Select("service_station_id,promote_num").Where("hm_id = ?", bindInfo.ManagerID).First(&newHealthManager).Error; nHMErr != nil {
				return nHMErr
			}
			var userInfo user.User
			// 修改用户信息
			if uIErr := tx.Where("id = ? ", bindInfo.UserID).First(&userInfo).
				Updates(map[string]interface{}{
					"health_manager_id":  bindInfo.ManagerID,
					"service_station_id": newHealthManager.ServiceStationID,
				}).Error; uIErr != nil {
				return uIErr
			}
			// 修改健管师信息
			*newHealthManager.PromoteNum += 1
			if uErr := tx.Model(&manager.HealthManager{}).Where("hm_id = ? ", bindInfo.ManagerID).Update("promote_num", *newHealthManager.PromoteNum).Error; uErr != nil {
				return uErr
			}
		}
		return err
	})
}

// GetBind 根据id获取用户绑定健管师记录
// Author [G-YT](https://gitcode.com/G-YT)
func (bindService *BindService) GetBind(id string) (Bind user.BindRecord, err error) {
	err = global.GVA_DB.Where("id = ?", id).First(&Bind).Error
	return
}

// GetUserBindManageInfoList 分页获取用户绑定健管师记录
// Author [G-YT](https://gitcode.com/G-YT)
func (bindService *BindService) GetUserBindManageInfoList(info userReq.BindRecordSearch) (list []user.BindRecord, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&user.BindRecord{})
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.ManagerID != 0 {
		db = db.Where("managerID = ?", info.ManagerID)
	}
	if info.Status != 0 {
		db = db.Where("status = ?", info.Status)
	}
	if info.UserID != 0 {
		db = db.Where("userID = ?", info.UserID)
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}

	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}

	err = db.Find(&list).Error
	return list, total, err
}
